//
//  DateComponents.swift
//  Documentation
//
//  Created by Toj on 11/13/23.
//

public struct DateComponents : ReferenceConvertible, Hashable, Equatable, Sendable {

    public typealias ReferenceType = NSDateComponents

    /**
     初始化
     * calendar: 日历
     * timeZone: 时区
     * era: 时代
     * year: 年
     * month: 月
     * day: 日
     * hour: 时
     * minute: 分
     * second: 秒
     * nanosecond: 纳秒
     * weekday: 一周的第几天, 通常从周日开始为1, 即周三为4
     * weekdayOrdinal: 本月的第几个weekday
     * * 若今天为周三: 表示今天为本月的第几个周三.
     * * 若本月是周四为1号: 那么周三则是在上个月, 虽然今天是第3周, 但此处则为2.
     * quarter: 季度, 0-3, 0表示12月1月2月.
     * weekOfMonth: 本月第几周.
     * weekOfYear: 本年第几周.
     * yearForWeekOfYear: ISO8601标准下的年份.
     * * 该标准一年有52或53周, 在最后一周时, 可能会出现该周属于2020年, 但在ISO8601标准, 该周属于2021年.
     */
    public init(
        calendar: Calendar? = nil,
        timeZone: TimeZone? = nil,
        era: Int? = nil,
        year: Int? = nil,
        month: Int? = nil,
        day: Int? = nil,
        hour: Int? = nil,
        minute: Int? = nil,
        second: Int? = nil,
        nanosecond: Int? = nil,
        weekday: Int? = nil,
        weekdayOrdinal: Int? = nil,
        quarter: Int? = nil,
        weekOfMonth: Int? = nil,
        weekOfYear: Int? = nil,
        yearForWeekOfYear: Int? = nil
    )

    /// calendar: 日历
    public var calendar: Calendar?
    /// timeZone: 时区
    public var timeZone: TimeZone?

    /// 时代
    public var era: Int?

    /// 年
    public var year: Int?

    /// 月
    public var month: Int?

   /// 日
    public var day: Int?

    /// 时
    public var hour: Int?

    /// 分
    public var minute: Int?

    /// 秒
    public var second: Int?

    /// 纳秒
    public var nanosecond: Int?

    /// 一周的第几天. 通常从周日开始为1, 即周三为4
    public var weekday: Int?

    /// 本月的第几个weekday
    /// NOTE:
    /// 若今天为周三: 表示今天为本月的第几个周三.
    /// 若本月是周四为1号: 那么周三则是在上个月, 虽然今天是第3周, 但此处则为2.
    public var weekdayOrdinal: Int?
   
    /// 季度, 0-3, 0表示12月1月2月.
    public var quarter: Int?

    /// 本月第几周.
    public var weekOfMonth: Int?

    /// 本年第几周.
    public var weekOfYear: Int?

    /// ISO 8601周编号年份。
    /// 公历定义一周有7天, 一年有365天, 闰年有366天.
    /// 然而, 365或366都不能平均分成7天的一周,
    /// 所以通常情况下, 一年的最后一周在下一年的某一天结束, 而一年的第一周在前一年开始.
    /// 为了协调这一点，ISO8601定义了一个以周为编号的年, 由52或53个完整的周(364或371天)组成,
    /// 这样, 一年的第一周被指定为包含该年第一个星期四的周.
    ///
    /// 可以将yearForWeekOfYear属性与weekOfYear和weekday属性一起使用,
    /// 以获得与一年中给定一周的特定工作日相对应的日期.
    /// 例如, 2005年(ISO 2005- w53 -6)第53周的第6天对应于公历2005年1月1日星期六.
    /// -注意: 在使用该值的日历上下文中解释该值.
    public var yearForWeekOfYear: Int?

    /// 本月是否为闰月
    public var isLeapMonth: Bool?

    /// 日期组件表示的日期, 日期组件的calendar不能为nil
    public var date: Date? { get }

    /// 设置属性
    @available(macOS 10.9, iOS 8.0, *)
    public mutating func setValue(_ value: Int?, for component: Calendar.Component)

    /// 获取属性
    @available(macOS 10.9, iOS 8.0, *)
    public func value(for component: Calendar.Component) -> Int?

    /// calendar里是否是有效日期
    /// 必须设置calendar, 否则一直是false
    @available(macOS 10.9, iOS 8.0, *)
    public var isValidDate: Bool { get }

   /// 指定的calendar里是否是有效日期
    @available(macOS 10.9, iOS 8.0, *)
    public func isValidDate(in calendar: Calendar) -> Bool

    public func hash(into hasher: inout Hasher)

    public static func == (lhs: DateComponents, rhs: DateComponents) -> Bool

    public var hashValue: Int { get }
}
